package com.lizy.sential.demo.service;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class TestService2 {

    /**
     * @SentinelResurce 改善接口中资源定义 和 被流控降级的代码
     * 属性：
     *  1.value : 定义资源
     *  2.blockHandler: 设置流控降级后的处理方法(默认该方法必须和资源定义在同一个类中)
     *  3. 如果不想在同一个类，可以放到blockHandlerClass属性
     *  4. 当接口出现异常可以使用fallback进行处理
     *  5. 流控降级的优先级要高于fallback
     * @return
     */
    @SentinelResource(value = "test2", blockHandler = "myBlockHandler", fallback = "myFallBack")
    public String test2(String name) {
        initFlowRules();
        UUID uuid = UUID.randomUUID();

        //验证fallback属性
        int i = 1/0;
        return uuid + "test2";
    }

    /**
     * 注意:
     *  1. 一定要public
     *  2. 返回值一定要和源方法保持一直
     *  3. 可以在参数最后添加BlockException: 通过异常的类型来判断是那种类型的降级
     * @param name
     * @return
     */
    public String myBlockHandler(String name, BlockException be) {
        UUID uuid = UUID.randomUUID();
        //通过异常的类型来判断是流控还是降级
        System.out.println(be instanceof FlowException);
        return uuid + "myBlockHandler";
    }

    public String myFallBack(String name, Throwable e) {
        UUID uuid = UUID.randomUUID();
        return uuid + "myFallBack";
    }


    /**
     * 定义规则
     */
    private void initFlowRules() {
        //流控规则
        List<FlowRule> flowRules = new ArrayList<>();
        FlowRule flowRule = new FlowRule();
        flowRule.setResource("test2");
        //设置qps阈值： 超过1s一次就抛出异常
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        flowRule.setCount(1);
        flowRules.add(flowRule);

        //加载配置好的规则
        FlowRuleManager.loadRules(flowRules);
    }
}
